package com.jianan.mis.app.menu;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.part.ViewPart;

import com.jianan.mis.data.domain.Group;
import com.jianan.mis.data.domain.Session;
import com.jianan.mis.data.domain.View;
import com.jianan.mis.data.domain.module.FunctionEntry;
import com.jianan.mis.data.domain.module.ITreeEntry;
import com.jianan.mis.data.domain.module.ModuleEntry;
import com.jianan.mis.service.GroupService;
import com.jianan.mis.sys.IImageKeys;
import com.jianan.mis.sys.IMessageKeys;
import com.jianan.mis.sys.ImageManager;
import com.jianan.mis.sys.SpringBeanFactory;
import com.jianan.mis.util.StringUtils;

public class MenuView extends ViewPart {
	public static final String ID = "com.jianan.mis.app.menu.MenuView";

	private static List<FunctionEntry> functions = new ArrayList<FunctionEntry>();

	private Text searchText;

	private RefreshMenuAction refreshAction;

	private TreeViewer treeViewer;

	private Tree tree;
	
	private GroupService groupService;

	class TreeLabelProvider extends LabelProvider {
		public String getText(Object element) {
			return ((ITreeEntry) element).getName();
		}

		public Image getImage(Object element) {
			if (element instanceof ModuleEntry)
				return ImageManager.getImage(IImageKeys.MODULE);
			else if (element instanceof FunctionEntry)
				return ImageManager.getImage(IImageKeys.FUNCTION);
			else
				return null;
		}
	}

	class TreeContentProvider implements IStructuredContentProvider,
			ITreeContentProvider {
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}

		public void dispose() {
		}

		public Object[] getElements(Object inputElement) {
			if (inputElement instanceof List) {
				List list = (List) inputElement;
				return list.toArray();
			} else {
				return new Object[0];
			}
		}

		public Object[] getChildren(Object parentElement) {
			ITreeEntry entry = (ITreeEntry) parentElement;
			List list = entry.getChildren();
			if (list == null || list.isEmpty())
				return new Object[0];
			else
				return list.toArray();
		}

		public Object getParent(Object element) {
			return null;
		}

		public boolean hasChildren(Object element) {
			ITreeEntry entry = (ITreeEntry) element;
			List list = entry.getChildren();
			if (list == null || list.isEmpty())
				return false;
			else
				return true;
		}
	}

	/**
	 * Create contents of the view part
	 * 
	 * @param parent
	 */
	@Override
	public void createPartControl(Composite parent) {
		
		if(!initializeServices()) {
			MessageDialog.openError(getViewSite().getShell(),
					IMessageKeys.OPEN_VIEW_FAIL, IMessageKeys.SERVICE_UNAVAILABLE);
			return;
		}
		
		this.setTitleImage(ImageManager.getImage(IImageKeys.MODULES_TITLE));

		Composite container = new Composite(parent, SWT.NONE);
		final GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 2;
		container.setLayout(gridLayout);

		final Label searchLabel = new Label(container, SWT.NONE);
		searchLabel.setText("功能搜索:");

		searchText = new Text(container, SWT.BORDER);
		searchText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		searchText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				treeViewer.setInput(null);
				if (searchText.getText().equals("")) {
					createModuleTree();
					return;
				}
				
				//遍历功能，寻找包含搜索字段的功能
				List<ITreeEntry> modulesResult = new ArrayList<ITreeEntry>();
				List<ITreeEntry> functionsResult = new ArrayList<ITreeEntry>();
				for (FunctionEntry function : functions) {
					if(com.jianan.mis.util.StringUtils.contains(function.getName(), searchText.getText().trim())) {
						functionsResult.add(function);
					}
				}

				// 显示搜索结果
				ModuleEntry moduleResult = new ModuleEntry("搜索结果");
				moduleResult.setChildren(functionsResult);
				modulesResult.add(moduleResult);
				treeViewer.setInput(modulesResult);
				treeViewer.expandAll();
			}
		});

		treeViewer = new TreeViewer(container, SWT.BORDER);
		treeViewer.setLabelProvider(new TreeLabelProvider());
		treeViewer.setContentProvider(new TreeContentProvider());
		createModuleTree();
		tree = treeViewer.getTree();
		tree.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				if (e.item.getData() instanceof FunctionEntry) {
					FunctionEntry function = (FunctionEntry) e.item.getData();
					try {
						if(StringUtils.isNotEmpty(function.getViewId())) {
							getViewSite().getWorkbenchWindow().getActivePage()
								.showView(function.getViewId());
						}
					} catch (Exception ex) {
						ex.printStackTrace();
						MessageDialog.openError(e.display.getActiveShell(),
								IMessageKeys.OPEN_VIEW_FAIL, ex.getMessage());
					}
				}
			}
		});
		tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));

		createActions();
		initializeToolBar();
		initializeMenu();
	}
	
	private boolean initializeServices() {
		groupService = (GroupService) SpringBeanFactory.getBean("groupService");
		if(groupService == null) {
			return false;
		}
		return true;
	}

	/**
	 * Create the actions
	 */
	private void createActions() {
		// Create the actions
		refreshAction = new RefreshMenuAction();
	}

	/**
	 * Initialize the toolbar
	 */
	private void initializeToolBar() {
		IToolBarManager toolbarManager = getViewSite().getActionBars()
				.getToolBarManager();
		toolbarManager.add(refreshAction);
	}

	/**
	 * Initialize the menu
	 */
	private void initializeMenu() {
		IMenuManager menuManager = getViewSite().getActionBars()
				.getMenuManager();
		menuManager.add(refreshAction);
	}
	
	/**
	 * 构建模块树
	 *
	 */
	private void createModuleTree() {
		treeViewer.setInput(getModuleTree());
		treeViewer.expandAll();
	}

	/**
	 * 取得模块树
	 */
	private Object getModuleTree() {
		List<ITreeEntry> modules = MenuContent.getMenu();
		functions.clear();
		
		Set<String> enabledViews = new HashSet<String>();
		for (String groupCode : Session.getInstance().getGroups()) {
			Group group = groupService.findByCode(groupCode);
			if (group != null) {
				Set<View> views = group.getViews();
				if (views != null) {
					for (View view : views) {
						enabledViews.add(view.getViewId());
					}
				}
			}
		}
		
		if(enabledViews.size() <= 0) {
			for (ITreeEntry module : modules) {
				module.getChildren().clear();
			}
		} else {
			// 根据权限过滤view
			List<ITreeEntry> disabledFunctions = new ArrayList<ITreeEntry>();
			for (ITreeEntry module : modules) {
				for (ITreeEntry function : module.getChildren()) {
					FunctionEntry functionEntry = (FunctionEntry) function;
					if(enabledViews.contains(functionEntry.getViewId())) {
						functions.add(functionEntry);
					} else {
						disabledFunctions.add(function);
					}
				}
				module.getChildren().removeAll(disabledFunctions);
				disabledFunctions.clear();
			}
		}
		
		return modules;
	}

	@Override
	public void setFocus() {
		// Set the focus
	}

	class RefreshMenuAction extends Action {

		public final static String ID = "com.jianan.app.menu.refreshMenu";

		public RefreshMenuAction() {
			setId(ID);
			setActionDefinitionId(ID);
			setText("刷新模块列表(&R)");
			setToolTipText("刷新模块列表");
			setImageDescriptor(ImageManager.getImageDescriptor(IImageKeys.REFRESH));
		}

		public void run() {
			searchText.setText("");
			createModuleTree();
		}
	}
}